package pokeronlab_2014.mcts;

public class MCTSDecision {

	/**
	 * Az MCTS algoritmus hányszor fusson le egymás után
	 */
	int iterNumber = 1000;

	public TreeNode root = null;

	/**
	 * A flopon amikor mi jövünk először beállítjuk a gyökércsúcsot
	 */
	public void setTreeRoot(TreeNode newRoot) {
		root = newRoot;
	}

	public boolean isTreeRootNull() {
		if (root == null) {
			return true;
		} else {
			return false;
		}
	}

	// nagyon jól hangzik, de nem-nem
	// /**
	// * @param action
	// * 0=fold, 1=check/call, 2=raise
	// * @param playerID
	// */
	// public void stepDownOneAction(int action, int playerID) {
	// if(!root.hasChildren()){
	// root.expand();
	// }
	// root = root.getChild(action);
	// }

	// /**
	// * a fában egy szinttel lejjebb lépés,
	// * mikor új lap érkezik az asztalon
	// *
	// * @param card a river vagy turn lap
	// *
	// */
	//
	// public void stepDownOneNewCard(int card) {
	// if(!root.hasChildren()){
	// root.expand();
	// }
	// root = root.getChild(card);
	// }

	/**
	 * Visszaadja a döntéshozó által választott döntést
	 * 
	 * @return A döntéshozó által választott döntés
	 */
	public int getDecision() {
		for (int i = 0; i < iterNumber; i++) {
			// a gyökér lesz az aktuálisan választott elem
			TreeNode selectedNode = root;
			// selection futtatása
			selectedNode = selection(selectedNode);
			// expansion futtatása
			selectedNode = expansion(selectedNode);
			// szimuláció futtatása, egy másolattal, majd az érték eltárolása
			double valueOfSimulation = simulation(new NodeFactory()
					.copyNode(selectedNode));
			// a kapott érték visszaterjesztése
			backpropagation(selectedNode, valueOfSimulation);
		}
		// döntés hozása
		// simán a legjobbat választja
		int chosenChild = 0;
		for (int i = 1; i < root.numberOfChildren; i++)
			if (root.getChild(i).totalValue > root.getChild(chosenChild).totalValue) {
				chosenChild = i;
			}
		// elég a számot visszaadni
		return chosenChild;
	}

	public TreeNode selection(TreeNode selection) {
		while (selection.hasChildren()) {
			selection = selection.select();
		}
		return selection;
	}

	public TreeNode expansion(TreeNode expandedNode) {
		expandedNode.expand();
		return expandedNode.select();
	}

	public double simulation(TreeNode simulatedNode) {
		while (simulatedNode.state.isGameOver()) {
			simulatedNode.simulate();
		}
		return new Evaluator().eval(simulatedNode);
	}

	public void backpropagation(TreeNode backpropagatedNode,
			double valueOfSimulation) {
		while (backpropagatedNode != null) {
			backpropagatedNode = backpropagatedNode
					.backpropagate(valueOfSimulation);
		}
	}

}